/*
* Copyright (c) 2007 by Kirill Kolodyazhniy.
* See the file "license.terms" for information on usage and redistribution.
*/

#ifndef M_ODEPHYSICSYSTEM_H
#define M_ODEPHYSICSYSTEM_H

#include "physicsystem.h"

#include "odeheaders.h"

namespace Engine
{
	/**
	*   ODE physic system implementation.
	*/
	class OdePhysicSystem: public PhysicSystem
	{
	public:

		/**
		*   Constructor
		*/
		OdePhysicSystem(const std::string& name);

		/**
		*   Destructor.
		*/
		virtual ~OdePhysicSystem();

		/**
		*   Set system gravity
		*/
		virtual void SetGravity(REAL x, REAL y, REAL z);

		/**
		*    Ode specific collision callback.
		*/
		friend void CollisionCallback(void *data, dGeomID o0, dGeomID o1);

	private:

		/**
		*   Create specific to implementation space.
		*/
		virtual Space* CreateSpaceImpl(const std::string& name);

		/**
		*   Create solid implementation.
		*/
		virtual Solid* CreateSolidImpl(const std::string& name);

		/**
		*   Make real simulation.
		*/
		virtual void Simulate(REAL step);

	private:

		static long m_odeInit;

		dWorldID m_worldID;

		dJointGroupID m_contactJointGroupID;

		dSpaceID m_rootSpaceID;
	};

	/**
	*   Factory for creating ode physic systems objects.
	*/
	class OdePhysicSystemFactory: public PhysicSystemFactory
	{
	public:

		OdePhysicSystemFactory():m_type("OdePhysic"){}

		/**
		*   Returns the factory type.
		*/
		virtual const std::string& GetType() const {return m_type;}

		/**
		*   Creates a new object.
		*   @param name Name of the object to create
		*   @return	An object created by the factory. The type of the object depends on	the factory.
		*/
		virtual OdePhysicSystem* CreateInstance( const std::string& name);

	private:

		std::string m_type;
	};
}

#endif
